package edu.jimei.projecttachy.service;

import edu.jimei.projecttachy.entity.Agent;
import edu.jimei.projecttachy.entity.Conversation;
import edu.jimei.projecttachy.entity.Message;
import edu.jimei.projecttachy.repository.AgentRepository;
import edu.jimei.projecttachy.repository.ConversationRepository;
import edu.jimei.projecttachy.repository.MessageRepository;
import edu.jimei.projecttachy.repository.DataSourceRepository;
import edu.jimei.projecttachy.repository.ReportTaskRepository;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityNotFoundException;

/**
 * 聊天服务类，处理对话管理、消息生成和上下文整合
 */
@Service
public class ChatService {

    private final ChatClient chatClient;
    private final ConversationRepository conversationRepository;
    private final MessageRepository messageRepository;
    private final AgentRepository agentRepository;
    private final DataSourceRepository dataSourceRepository;
    private final ReportTaskRepository reportTaskRepository;

    /**
     * 构造函数，注入所需的仓库和客户端依赖
     *
     * @param chatClientBuilder AI聊天客户端构建器
     * @param conversationRepository 对话仓库
     * @param messageRepository 消息仓库
     * @param agentRepository 智能体仓库
     * @param dataSourceRepository 数据源仓库
     * @param reportTaskRepository 报告任务仓库
     */
    public ChatService(ChatClient.Builder chatClientBuilder,
                       ConversationRepository conversationRepository,
                       MessageRepository messageRepository,
                       AgentRepository agentRepository,
                       DataSourceRepository dataSourceRepository,
                       ReportTaskRepository reportTaskRepository) {
        this.chatClient = chatClientBuilder.build();
        this.conversationRepository = conversationRepository;
        this.messageRepository = messageRepository;
        this.agentRepository = agentRepository;
        this.dataSourceRepository = dataSourceRepository;
        this.reportTaskRepository = reportTaskRepository;
    }


    /**
     * 生成对话响应
     *
     * @param conversationId 对话ID
     * @param userContent 用户消息内容
     * @param dataSourceId 数据源ID（可选）
     * @param reportId 报告ID（可选）
     * @return 生成的智能体消息
     */
    @Transactional
    public Message generateResponse(Long conversationId, String userContent, Long dataSourceId, Long reportId) {
        // 1. Find the conversation.
        Conversation conversation = conversationRepository.findById(conversationId)
                .orElseGet(() -> createNewConversation(userContent));

        // 2. Create and save the user's message
        Message userMessage = new Message();
        userMessage.setConversation(conversation);
        userMessage.setSenderType(Message.SenderType.user);
        userMessage.setContent(userContent);
        messageRepository.save(userMessage);

        // 3. Build the context string from data source or report
        StringBuilder contextBuilder = new StringBuilder();
        if (conversation.getAgent() != null && conversation.getAgent().getSystemPrompt() != null) {
            contextBuilder.append(conversation.getAgent().getSystemPrompt());
            contextBuilder.append("\n\n");
        }

        if (dataSourceId != null) {
            dataSourceRepository.findById(dataSourceId).ifPresent(dataSource -> {
                contextBuilder.append("--- Data Source Context ---\n");
                contextBuilder.append("Name: ").append(dataSource.getName()).append("\n");
                contextBuilder.append("Type: ").append(dataSource.getType()).append("\n");
                contextBuilder.append("Status: ").append(dataSource.getStatus()).append("\n");
                contextBuilder.append("--- End Data Source Context ---\n\n");
            });
        }

        if (reportId != null) {
            reportTaskRepository.findById(reportId).ifPresent(report -> {
                contextBuilder.append("--- Report Context ---\n");
                contextBuilder.append("Report Name: ").append(report.getName()).append("\n");
                contextBuilder.append("Status: ").append(report.getStatus()).append("\n");
                contextBuilder.append("Content: ").append(report.getContent()).append("\n");
                contextBuilder.append("--- End Report Context ---\n\n");
            });
        }


        // 4. Build the prompt with context
        ChatClient.ChatClientRequestSpec promptRequest = chatClient.prompt()
                .user(userContent);

        if (!contextBuilder.isEmpty()) {
            promptRequest.system(contextBuilder.toString());
        }


        // 5. Call the AI model to get a response
        String agentContent = promptRequest.call().content();

        // 6. Create and save the agent's message
        Message agentMessage = new Message();
        agentMessage.setConversation(conversation);
        agentMessage.setSenderType(Message.SenderType.agent);
        agentMessage.setContent(agentContent);
        return messageRepository.save(agentMessage);
    }

    @Transactional
    public void selectAgentForConversation(Long conversationId, Long agentId) {
        Conversation conversation = conversationRepository.findById(conversationId)
                .orElseThrow(() -> new EntityNotFoundException("Conversation not found with id: " + conversationId));

        Agent agent = agentRepository.findById(agentId)
                .orElseThrow(() -> new EntityNotFoundException("Agent not found with id: " + agentId));

        conversation.setAgent(agent);
        conversationRepository.save(conversation);
    }

    private Conversation createNewConversation(String userContent) {
        Conversation newConversation = new Conversation();
        // In a real app, user ID would come from the security context
        newConversation.setUserId(1L);

        String title = userContent.length() > 50 ? userContent.substring(0, 50) + "..." : userContent;
        newConversation.setTitle(title);

        return conversationRepository.save(newConversation);
    }
} 